package com.feib.soeasy.dao.hibernate;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Query;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.stereotype.Repository;

import com.feib.soeasy.dao.UserLoginControlDao;
import com.feib.soeasy.model.Group;
import com.feib.soeasy.model.User;
import com.feib.soeasy.model.UserLoginControl;
import com.feib.soeasy.pagination.PaginatedList;
import com.feib.soeasy.util.UserUtil;

/**
 * @title (#)UserLoginControlHibernateDao.java<br>
 * @description <br>
 * @author Anson Tsai<br>
 * @version 1.0.0 2010/11/25
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @2010/12/5 create by Anson Tsai<br>
 */
@Repository("userLoginControlDao")
public class UserLoginControlHibernateDao extends BaseHibernateDao<UserLoginControl, Long> implements UserLoginControlDao {

    
    public UserLoginControl findByUer(User user)
    {
        if (null == user || null == user.getUserPk())
            return null;
        
        DetachedCriteria criteria = DetachedCriteria.forClass(this.getPersistentClass());
        criteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY);
        criteria.add(Restrictions.eq("user", user));

        @SuppressWarnings("unchecked")
        List<UserLoginControl> users = this.getHibernateTemplate().findByCriteria(criteria);

        return DataAccessUtils.singleResult(users);
    }
    
    @Override
    public UserLoginControl findByUerIdGroupNo(String userId, String groupNo) {

        if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(groupNo))
            return null;

        DetachedCriteria criteria = DetachedCriteria.forClass(this.getPersistentClass());
        criteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY);
        
        DetachedCriteria userCriteria = criteria.createCriteria("user");
        userCriteria.add(Restrictions.eq("userId", userId));

        DetachedCriteria groupCriteria = userCriteria.createCriteria("group");        
        groupCriteria.add(Restrictions.eq("groupNo", groupNo));

        @SuppressWarnings("unchecked")
        List<UserLoginControl> users = this.getHibernateTemplate().findByCriteria(criteria);

        return DataAccessUtils.singleResult(users);
    }

    @SuppressWarnings("unchecked")
    @Override
    public PaginatedList<UserLoginControl> queryEnabledInfoByUserIdGroupNo(String userId, String groupNo, boolean isBank, PaginatedList<UserLoginControl> paginationConfig) {
        PaginatedList<UserLoginControl> result = new PaginatedList<UserLoginControl>();
        
        result.setPageSize(paginationConfig.getPageSize());
        result.setPageNumber(paginationConfig.getPageNumber());
        result.setSortCriterion(paginationConfig.getSortCriterion());
        result.setSortDirection(paginationConfig.getSortDirection());
        
        result.setFullListSize(super.countByDetachedCriteria(
                        createDetachedCriteriaByUserIdGroupNo(userId, groupNo, isBank)));
        
        // 筆數大於0
        if (0 < result.getFullListSize())
        {
            DetachedCriteria criteria = createDetachedCriteriaByUserIdGroupNo(userId, groupNo, isBank);

            //排序
            if (null != paginationConfig.getSortCriterion())
            {
                // 由小到大
                if (PaginatedList.SORT_DIRECTION_ASC == paginationConfig.getSortDirection())
                {
                    criteria.addOrder(Order.asc(paginationConfig.getSortCriterion()));
                }
                else // 由大到小
                {
                    criteria.addOrder(Order.asc(paginationConfig.getSortCriterion()));
                }
            }
            int maxResults = result.getPageSize(); //the maximum number of results
            int firstResult = result.getFirstIndexForCurrentPage();  //the first result to retrieve, numbered from 0
            result.setPaginatedList(this.getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults));
        }
        return result;        
    }

    protected DetachedCriteria createDetachedCriteriaByUserIdGroupNo(String userId, String groupNo, boolean isBank)
    {
        DetachedCriteria criteria = DetachedCriteria.forClass(this.getPersistentClass());
        criteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY);
        
        if (isBank)
        {
            // 銀行端查詢
            DetachedCriteria userCriteria = criteria.createCriteria("user");
            DetachedCriteria groupCriteria = userCriteria.createCriteria("group");
            
            /* 排除自己 */
            userCriteria.add(Restrictions.not(Restrictions.eq("userId", UserUtil.getUserId())));
            
            // 只能查出帳業者的 admin
            if ( StringUtils.isNotBlank(groupNo))
            {
                /*
                 * 20110111反應問題.doc, UAT問題反應
                 * 銀行端有admin權限者，可強迫登出任何帳號，包含帳單業者及銀行端所有使用者(實務需要，有客戶或銀行使用者比較急，會電話通知admin權限馬上強迫登出)。
                 */
                //userCriteria.add(Restrictions.eq("userId", "admin"));
                groupCriteria.add(Restrictions.like("groupNo", groupNo, MatchMode.START));
                groupCriteria.add(Restrictions.not(Restrictions.eq("groupType", Group.GROUP_TYPE_BANK)));
            }
            else
            {
                // 只能查詢 Bank 的帳號
                groupCriteria.add(Restrictions.eq("groupType", Group.GROUP_TYPE_BANK));
                
                if ( StringUtils.isNotBlank(userId))
                {
                    userCriteria.add(Restrictions.like("userId", userId, MatchMode.START));
                }
            }
        }
        else
        {
            // 帳單業者查詢            
            DetachedCriteria userCriteria = criteria.createCriteria("user");
            
            /* 排除自己 */
            userCriteria.add(Restrictions.not(Restrictions.eq("userId", UserUtil.getUserId())));
            
            if ( StringUtils.isNotBlank(userId))
                userCriteria.add(Restrictions.like("userId", userId, MatchMode.START));
            
            DetachedCriteria groupCriteria = userCriteria.createCriteria("group");
            groupCriteria.add(Restrictions.eq("groupNo", groupNo));
            groupCriteria.add(Restrictions.not(Restrictions.eq("groupType", Group.GROUP_TYPE_BANK)));
        }
        
        
        criteria.add(Restrictions.eq("actived", Boolean.TRUE));
        
        return criteria;
    }

    @Override
    public void disableUserLoginInfo(ArrayList<UserLoginControl> userLoginInfos) {
        StringBuffer hql = new StringBuffer();
        hql.append("update UserLoginControl set actived = :actived  ");
        hql.append("where userLoginConPk = :userLoginConPk ");
        for(UserLoginControl u : userLoginInfos){
            if (null != u)
            {
                Query query = getSession().createQuery(hql.toString());
                query.setParameter("actived", Boolean.FALSE);
                query.setParameter("userLoginConPk", u.getUserLoginConPk());
                query.executeUpdate();
            }
        }
    }
}
